/**
@author 迷途小羔羊
2022.09.27
*/
module GYLite
{
    export class GYBitmapNode extends egret.sys.BitmapNode implements IUpdate{    
		public left:number;
		public right:number;
		public top:number;       
		public bottom:number;
		public color:number;
        protected fillMode:string;
        protected scale9Grid:egret.Rectangle;
		protected _updating:boolean;

        protected _WMidData:egret.Texture;
		protected _HMidData:egret.Texture;
		
		// protected _imgWidth:number;
		// protected _imgHeight:number;
		protected _scale9GridRect:Scale9GridRect;
		protected _clipX:number;
		protected _clipY:number;
		protected _drawX:number;
		protected _drawY:number;
		protected _mode:number;		
		protected _invalidDraw:boolean;		
		protected _renderMatrix:egret.Matrix;
		protected _repeat:boolean;
		protected _repeatWidth:number;
		protected _repeatHeight:number;
		protected _repeatX:number;
		protected _repeatY:number;
		protected _width:number;
		protected _height:number;
        protected _texture:egret.Texture;
		protected _matrix:egret.Matrix;
		protected _angle:number;
		protected _tx:number;
		protected _ty:number;
		protected _alpha:number;		
        public constructor(value?: egret.Texture,rect:Scale9GridRect=null){
            super();
			var s = this;		
			s.top = s.left = Number.MAX_VALUE;			
			s.bottom = s.right = Number.MIN_VALUE;			
			s._tx = s._ty =0;
			s._clipX = 0;
			s._clipY = 0;
			s._drawX = 0;
			s._drawY = 0;
			s._invalidDraw = false;
			s._mode = ScaleMode.SCALE;			
			s._repeatX = 0;
			s._repeatY = 0;
			s._repeatWidth=NaN;
			s._repeatHeight=NaN;
			// s._imgWidth = NaN;
			// s._imgHeight = NaN;
			s._width = NaN;
			s._height = NaN;
			
			s.scale9GridRect = rect;
			s._texture = value;
			s._matrix = new egret.Matrix;
			s._angle = 0;
			s._alpha = 1;
			s.invalidDraw();
        }
		public setRect(l:number,r:number,t:number,b:number):void
        {
            let s= this;
            if(l < s.left)
                s.left = l;
            if(t < s.top)
                s.top = t;
            if(r > s.right)
                s.right = r;
            if(b > s.bottom)
                s.bottom = b;
        }
		/**设置节点透明度*/
		public setAlpha(a:number):void
		{
			this._alpha = a;
		}
		/**x y位置偏移量*/
		public translate(x:number,y:number):void
		{
			let s= this;			
			s._matrix.translate(x,y);
		}
		/**设置x y纹理偏移*/
		public setOffset(x:number,y:number):void
		{
			let s= this;
			s._tx = x;
			s._ty = y;
		}
		public set angle(agl:number)
		{
			let s = this;			
			if(s._angle == agl)return;
			s._angle = agl;
			if(agl % MathConst.DOUBLE_PI == 0)
				s.matrix = null;
			else			
				s._matrix.rotate(agl);				
				
		}
		public get angle():number
		{
			return this._angle;
		}
		public set rotation(degree:number)
		{
			let s = this;
			s.angle = degree * MathConst.ROTATION_ANGLE;
		}
		public get rotation():number
		{
			return this._angle * MathConst.ANGLE_ROTATION;
		}
		
        private draw(tex:egret.Texture):void
		{var s = this;				
			if(tex==null)
				return;				
			s.imageWidth = tex.$sourceWidth;
			s.imageHeight = tex.$sourceHeight;
			if(s._mode == ScaleMode.FREE)	
			{				
				s.image = tex.$bitmapData;
				s.matrix = s._matrix;
				s.alpha = s._alpha;
				GYLite.GYSprite._matrix.identity();
				s.beginBitmapFill(GYLite.GYSprite._matrix,false);
				s.drawRect(0,0,tex.$bitmapWidth,tex.$bitmapHeight);//多画一像素保证内容完整,egret渲染问题
				return;
			}
			
			var sclX:number,sclY:number;
			var tempY1:number,tempY2:number,tempY3:number,tempX1:number,tempX2:number,tempX3:number;			
			var destW:number,destH:number;
			var isGL:boolean;
			var topGap:number,bottomGap:number,leftGap:number,rightGap:number;
			var offsetX:number,offsetY:number,paddingW:number,paddingH:number;			
			var mustClip:boolean;
			var imgWidth:number,imgHeight:number;
			
					
			if(egret.nativeRender)
			{
				if(s._scale9GridRect)
					s.scale9Grid = new egret.Rectangle(s._scale9GridRect.leftGap,s._scale9GridRect.topGap,imgWidth - s._scale9GridRect.leftGap - s._scale9GridRect.rightGap,imgHeight - s._scale9GridRect.bottomGap - s._scale9GridRect.topGap)
				else
					s.scale9Grid = null;
				if(s._mode == ScaleMode.SCALE || s._scale9GridRect)				
					s.fillMode = egret.BitmapFillMode.SCALE;
				else if(s._mode == ScaleMode.CLIP)
					s.fillMode = egret.BitmapFillMode.CLIP;
				else if(s._mode == ScaleMode.REPEAT)
					s.fillMode = egret.BitmapFillMode.REPEAT;
				return;
			}
			// if(s._scale9GridRect.gridMode == ScaleGridMode.v3Grid)			
			// 	s._scale9GridRect.leftGap = s._scale9GridRect.rightGap = 0;
			// else if(s._scale9GridRect.gridMode == ScaleGridMode.h3Grid)
			// 	s._scale9GridRect.topGap = s._scale9GridRect.bottomGap = 0;
			
			isGL = egret.Capabilities.renderMode == "webgl" && CommonUtil.GYIs(tex, GYLite.GYDrawBitmapData);			
			s.clearBitmapFill();			
			s.matrix = s._matrix;
			s.alpha = s._alpha;
			s.image = tex.$bitmapData;
			
			imgWidth=tex.$bitmapWidth;//$bitmapWidth和textureWidth是有区别的，textureWidth是原始小图宽高(不包括透明像素边距)，前者是裁切透明像素后的宽高,使用textureWidth会导致截取图集区域不准确
			imgHeight=tex.$bitmapHeight;
			
			paddingW = tex.textureWidth - tex.$bitmapWidth * egret.$TextureScaleFactor;
			paddingH = tex.textureHeight - tex.$bitmapHeight * egret.$TextureScaleFactor;			
			if(s._width == s._width)
				destW = s._width - paddingW;
			else
				destW = imgWidth;				
				
			if(s._height == s._height)
				destH = s._height - paddingH;				
			else
				destH = imgHeight;		
			if(destW <= 0 || destH <= 0)
				return;
			if(s._scale9GridRect)
			{//九宫格减去图集小图透明像素偏移量
				offsetX = tex.$offsetX;
				offsetY = tex.$offsetY;			
				topGap = (s._scale9GridRect.gridMode == ScaleGridMode.h3Grid?0:s._scale9GridRect.topGap) - offsetY;
				bottomGap = (s._scale9GridRect.gridMode == ScaleGridMode.h3Grid?0:s._scale9GridRect.bottomGap) - paddingH + offsetY;
				leftGap = (s._scale9GridRect.gridMode == ScaleGridMode.v3Grid?0:s._scale9GridRect.leftGap) - offsetX;
				rightGap = (s._scale9GridRect.gridMode == ScaleGridMode.v3Grid?0:s._scale9GridRect.rightGap) - paddingW + offsetX;
			}
			
			mustClip = s._scale9GridRect && (destW < leftGap + rightGap || destH < topGap + bottomGap);//不符合九宫格条件，强制裁切	
			if(mustClip && (destW > imgWidth || destH > imgHeight))return;//小于原图大小，不绘制
			if(s._scale9GridRect == null || mustClip)
			{				
				GYSprite._matrix.a=1;
				GYSprite._matrix.d=1;
				GYSprite._matrix.tx=s._drawX-s._clipX;
				GYSprite._matrix.ty=s._drawY-s._clipY;
				if(s._mode == ScaleMode.CLIP || mustClip)
					s.beginBitmapFill(GYSprite._matrix,false);
				else if(s._mode == ScaleMode.SCALE)
				{
					GYSprite._matrix.a=destW / imgWidth;
					GYSprite._matrix.d=destH / imgHeight;
					s.beginBitmapFill(GYSprite._matrix,false);
				}
				else
				{	
					s.beginBitmapFill(GYSprite._matrix,true);									
				}								
				s.drawRect(s._drawX,s._drawY,destW+1,destH+1);//多画一像素保证内容完整,egret渲染问题
				return;
			}			
			tempX1=destW-rightGap;
			tempX2=tempX1-leftGap;
			tempX3=destW-imgWidth;
			tempY1=destH-bottomGap;
			tempY2=tempY1-topGap;
			tempY3=destH-imgHeight;
			
			sclX=tempX2/(imgWidth-leftGap-rightGap);
			sclY=tempY2/(imgHeight-topGap-bottomGap);

			let is9Grid:boolean;
			is9Grid = s._scale9GridRect.gridMode == ScaleGridMode.s9Grid;
			//拉伸中部
			GYSprite._matrix.a=sclX;
			GYSprite._matrix.d=sclY;
			GYSprite._matrix.tx=0;
			GYSprite._matrix.ty=0;
			s.beginBitmapFill(GYSprite._matrix,false);
			s.drawRect(leftGap, topGap, tempX2, tempY2);
			if(s._scale9GridRect.gridMode == ScaleGridMode.v3Grid || is9Grid)
			{
				//拉伸头部
				GYSprite._matrix.a=sclX;
				GYSprite._matrix.d=1;
				GYSprite._matrix.tx=0;
				s.beginBitmapFill(GYSprite._matrix,false);						
				GYSprite._matrix.ty=(isGL?-imgHeight+topGap:0);
				s.drawRect(leftGap, 0, tempX2, topGap);				
				//拉伸底部
				GYSprite._matrix.a=sclX;
				GYSprite._matrix.d=1;
				GYSprite._matrix.tx=0;
				GYSprite._matrix.ty=(isGL?tempY1:tempY3);			
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(leftGap, tempY1, tempX2, bottomGap);
			}
			if(s._scale9GridRect.gridMode == ScaleGridMode.h3Grid || is9Grid)
			{
				//拉伸左部
				GYSprite._matrix.a=1;
				GYSprite._matrix.d=sclY;
				GYSprite._matrix.tx=0;
				GYSprite._matrix.ty=0;
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(0, topGap, leftGap, tempY2);				
				//拉伸右部
				GYSprite._matrix.a=1;
				GYSprite._matrix.d=sclY;
				GYSprite._matrix.tx=tempX3;
				GYSprite._matrix.ty=0;
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(tempX1, topGap,  rightGap, tempY2);
			}		
			if(is9Grid)
			{
				//四角
				GYSprite._matrix.a=1;
				GYSprite._matrix.d=1;
				GYSprite._matrix.tx=0;
				GYSprite._matrix.ty=(isGL?-imgHeight+topGap:0);
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(0, 0, leftGap, topGap);
				GYSprite._matrix.tx=tempX3;
				GYSprite._matrix.ty=(isGL?-imgHeight+topGap:0);
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(tempX1, 0, rightGap, topGap);
				GYSprite._matrix.tx=0;
				GYSprite._matrix.ty=(isGL?tempY1:tempY3);
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(0, tempY1, leftGap, bottomGap);
				GYSprite._matrix.tx=tempX3;
				GYSprite._matrix.ty=(isGL?tempY1:tempY3);
				s.beginBitmapFill(GYSprite._matrix,false);
				s.drawRect(tempX1, tempY1, rightGap, bottomGap);		
			}	
				
		}
        public beginBitmapFill(m:egret.Matrix, r:boolean):void
		{
			var s = this;			
			if(egret.nativeRender)
				throw(new Error("runTime模式不支持！beginBitmapFill"));						
			s._renderMatrix = m;
			s._repeat = r;
		}
		public drawRect(tX:number, tY:number, w:number, h:number):void
		{
			var s = this;
			if(egret.nativeRender)
				throw(new Error("runTime模式不支持！drawRect"));
			var node:any = s;
			var sclX:number,sclY:number;
			var displayWidth:number,displayHeight:number, stepWidth:number,stepHeight:number;
			var startX:number,startY:number,paddingX:number,paddingY:number;	
			var i:number,iLen:number,j:number,jLen:number,tempX:number;			
			var tex:egret.Texture;
			tex = s._texture;
			if(s._repeat)
			{
				sclX = s._renderMatrix.a;
				sclY = s._renderMatrix.d;
				displayWidth = (isNaN(s._repeatWidth)?tex.$bitmapWidth:s._repeatWidth)*sclX;
				displayHeight = (isNaN(s._repeatHeight)?tex.$bitmapHeight:s._repeatHeight)*sclY;
				paddingX = s._renderMatrix.tx % displayWidth;
				paddingY = s._renderMatrix.ty % displayHeight;				
				paddingX = (paddingX <= 0?-paddingX:displayWidth - paddingX);
				paddingY = (paddingY <= 0?-paddingY:displayHeight - paddingY);			
				startY = tY;				
				jLen = Math.ceil((paddingX + w) / displayWidth);
				iLen = Math.ceil((paddingY + h) / displayHeight);
				for (i = 0; i < iLen; ++i) {
					stepHeight = displayHeight - paddingY;
					stepHeight = Math.min(h - startY + tY, stepHeight);
					tempX = paddingX;	
					startX = tX;			
					for (j = 0; j < jLen; ++j) {
						stepWidth = displayWidth - tempX;
						stepWidth = Math.min(w - startX + tX, stepWidth);
						node.drawData.push(tex.$bitmapX + tempX + s._repeatX, tex.$bitmapY + paddingY + s._repeatY,stepWidth/sclX,stepHeight/sclY,tex.$offsetX + startX + s._tx,tex.$offsetY + startY + s._ty,stepWidth,stepHeight);						
						++node.renderCount;
						startX += stepWidth;
						if(tempX > 0)						
							tempX = 0;												
					}
					
					startY += stepHeight;
					if(paddingY > 0)									
						paddingY = 0;											
				}								
			}
			else
			{
				sclX = s._renderMatrix.a;
				sclY = s._renderMatrix.d;
				node.drawData.push(tex.$bitmapX -s._renderMatrix.tx+tX, tex.$bitmapY -s._renderMatrix.ty+tY,w/sclX,h/sclY,tex.$offsetX + tX + s._tx,tex.$offsetY + tY + s._ty,w,h);				
				++node.renderCount;
			}						
		}
		public clearBitmapFill():void
		{
			var s = this;			
			s.cleanBeforeRender();
		}
		public set repeatWidth(val:number)
		{
			this._repeatWidth = val;
		}
		/**重复模式的砖块宽度*/
		public get repeatWidth():number
		{
			return this._repeatWidth;
		}
		public set repeatHeight(val:number)
		{
			this._repeatHeight = val;
		}
		/**重复模式的砖块高度*/
		public get repeatHeight():number
		{
			return this._repeatHeight;
		}
		public set repeatX(val:number)
		{
			this._repeatX = val;
		}
		/**重复模式的起始X*/
		public get repeatX():number
		{
			return this._repeatX;
		}
		public set repeatY(val:number)
		{
			this._repeatY = val;
		}
		/**重复模式的起始Y*/
		public get repeatY():number
		{
			return this._repeatY;
		}
		public set width(val:number)
		{var s = this;
			if(s._width == val)
				return;
			s._width = val;			
			s.invalidDraw();
		}
		public get width():number
		{var s = this;
			return s._width==s._width?s._width:(s._texture?s._texture.textureWidth:0);
		}
		
		public set height(val:number)
		{var s = this;
			if(s._height == val)
				return;
			s._height=val;						
			s.invalidDraw();
		}
		public get height():number
		{var s = this;
			return s._height==s._height?s._height:(s._texture?s._texture.textureHeight:0);
		}
		/**绘制模式 @see ScaleMode
		 * @param val 0 拉伸 1 裁切 2 重复 */
		 public set mode(val:number)
		 {var s = this;
			 if(s._mode == val)return;
			 s._mode=val;
			 if(egret.nativeRender)return;			 
			 s.invalidDraw();
		 }
		public set scale9GridRect(value:Scale9GridRect) 
		{var s = this;
			if(s._scale9GridRect == value)
				return;
			s._scale9GridRect=value;
			s.invalidDraw();
		}
		public set clipX(val:number)
		{var s = this;
			if(s._clipX == val)
				return;
			s._clipX = val;
			s.invalidDraw();
		}
		public set clipY(val:number)
		{var s = this;
			if(s._clipY == val)
				return;
			s._clipY = val;
			s.invalidDraw();
		}
		/**裁切的s.x坐标*/
		public get clipX():number
		{var s = this;
			return s._clipX;	
		}
		/**裁切的s.y坐标*/
		public get clipY():number
		{var s = this;
			return s._clipY;
		}
		public set drawX(val:number)
		{var s = this;
			if(s._drawX == val)
				return;
			s._drawX = val;
			s.invalidDraw();
		}
		public set drawY(val:number)
		{var s = this;
			if(s._drawY == val)
				return;
			s._drawY = val;
			s.invalidDraw();
		}
		/**绘制点的s.x坐标*/
		public get drawX():number
		{var s = this;
			return s._drawX;	
		}
		/**绘制点的s.y坐标*/
		public get drawY():number
		{var s = this;
			return s._drawY;
		}
		
		/**刷新绘图*/
		public invalidDraw():void
		{var s = this;
			if(s._invalidDraw)
				return;
			s._invalidDraw = true;
			// s.displayChg(s.updateView);
			LayoutManager.addRenderFunc(s);
		}

		public get scale9GridRect():Scale9GridRect
		{var s = this;
			return s._scale9GridRect;
		}

		/**是否刷新中（内部使用请勿修改）*/
		public get updating():boolean
		{var s = this;
			return s._updating;
		}

		public set updating(value:boolean)
		{var s = this;
			s._updating = value;
		}
		public validDraw():void
		{
			let s= this;
			s.draw(s._texture);
		}

		public updateView():void
		{
			var s = this;			
			if(s._invalidDraw)
			{
				s.validDraw();
				s._invalidDraw = false;
			}
		}
    }
}